/**
  ******************************************************************************
  * @file    event_sys.c
  * @author  Yun
  * @version V1.3.0
  * @date    2025-02-21
  * @brief   事件系统核心实现
  * @license EULA (End User License Agreement)
  *          Copyright (c) 2025 星瑜科技自动化 Co., Ltd. All rights reserved.
  ******************************************************************************
  */

/*---------------------- Includes ----------------------*/
#include "event.h"

/*---------------------- 宏定义 ----------------------*/
/*!< 事件头链表长度 */
#define EVENT_HEAD_LEN       ((uint8_t)EVENT_ID_MAX - 1)

/*---------------------- 结构体定义 ----------------------*/
/**
  * @brief 事件节点结构体
  */
typedef struct Event_Node {
    void* pDevice;                      /*!< 关联设备指针 */
    Event_Callback_TypeDef pfnCallback; /*!< 事件回调函数 */
    struct Event_Node* pNext;           /*!< 下一节点指针 */
    uint8_t u8Pri;                      /*!< 事件优先级 0-255 */
    uint8_t uReserved;                  /*!< 保留字段 */
    uint16_t uReserved1;                /*!< 保留字段 */
} Event_Node_TypeDef;

/**
  * @brief 事件队列项结构体
  */
typedef struct Event_Queue {
    void* pDevice;                      /*!< 关联设备指针 */
    void* pArgs;                        /*!< 事件参数指针 */
    Event_Id_TypeDef u8Id;           /*!< 事件ID */
} Event_Queue_TypeDef;

/**
  * @brief 事件头节点结构体
  */
typedef struct Event_Head_Node {
    Event_Id_TypeDef u8Id;           /*!< 事件ID标识 */
    Event_Node_TypeDef* pNext;       /*!< 下一节点指针 */
} Event_Head_Node_TypeDef;

/**
  * @brief 事件控制器结构体
  */
typedef struct Event_Controller {
    Event_Queue_TypeDef EventQueue[EVENT_HAPPENED_MAX_NUM]; /*!< 事件队列数组 */
    uint32_t u32EventCount;                                 /*!< 当前队列中事件数量 */
    Event_Head_Node_TypeDef stEventHead[EVENT_HEAD_LEN];    /*!< 事件头节点数组 */
    Event_Node_TypeDef stEventPool[EVENT_POOL_MAX_NUM];     /*!< 事件节点内存池 */
    uint8_t u8EventPoolIndex;                               /*!< 事件池索引 */
    uint8_t u8EventQueuePushIndex;                          /*!< 队列写入索引 */
    uint8_t u8EventQueuePopIndex;                           /*!< 队列读取索引 */
    uint8_t u8EventState;                                   /*!< 事件系统状态 */
} Event_Controller_TypeDef;

/*---------------------- 静态变量 ----------------------*/
/**
  * @brief 事件控制器实例
  */
static Event_Controller_TypeDef stEventController = {
        .u8EventQueuePushIndex  = 0,
        .u8EventQueuePopIndex   = 0,
        .u32EventCount          = 0,
        .u8EventPoolIndex       = 0,
        .u8EventState           = EVENT_STATE_IDLE,
};

/*---------------------- 内部静态函数实现 ----------------------*/
/**
  * @brief  事件出队
  * @param  pstEvtQueue: 输出参数，接收事件数据
  * @retval uint8_t 1: 成功 0: 失败
  */
static uint8_t Event_Queue_Pop(Event_Queue_TypeDef* pstEvtQueue)
{
    if((stEventController.u32EventCount == 0) ||
       (stEventController.u8EventState != EVENT_STATE_IDLE)) {
        return 0;
    }
    stEventController.u8EventState = EVENT_STATE_BUSY;

    /* 循环队列处理 */
    if(stEventController.u8EventQueuePopIndex >= EVENT_HAPPENED_MAX_NUM) {
        stEventController.u8EventQueuePopIndex = 0;
    }

    /* 读取队列项 */
    *pstEvtQueue = stEventController.EventQueue[stEventController.u8EventQueuePopIndex];

    /* 清空队列项 */
    stEventController.EventQueue[stEventController.u8EventQueuePopIndex].u8Id = EVENT_NONE;
    stEventController.EventQueue[stEventController.u8EventQueuePopIndex].pDevice = NULL;
    stEventController.EventQueue[stEventController.u8EventQueuePopIndex].pArgs = NULL;
    stEventController.u8EventQueuePopIndex++;
    stEventController.u32EventCount--;

    stEventController.u8EventState = EVENT_STATE_IDLE;

    /* 系统周期事件重入队 */
    if(pstEvtQueue->u8Id == EVENT_SYS_CIRCLE)
    {
        Event_Queue_Push(pstEvtQueue->u8Id, pstEvtQueue->pDevice, pstEvtQueue->pArgs);
    }

    return 1;
}

/*!
 * @brief 事件触发
 * @param pstEvt: 事件数据
 * @return 1:成功 0:失败
 */
static uint8_t Event_Emit(Event_Queue_TypeDef* pstEvt)
{
    if(pstEvt->u8Id < 1 || pstEvt->u8Id > EVENT_ID_MAX) return 0;

    /* 遍历对应事件链表 */
    Event_Head_Node_TypeDef* pstEvtHeadNode = &(stEventController.stEventHead[pstEvt->u8Id - 1]);
    Event_Node_TypeDef* pstEvtNode = pstEvtHeadNode->pNext;
    while(pstEvtNode != NULL)
    {
        if(pstEvtNode->pfnCallback != NULL && pstEvtNode->pDevice == pstEvt->pDevice)
        {
            pstEvtNode->pfnCallback(pstEvt->pArgs);
        }
        pstEvtNode = pstEvtNode->pNext;
    }

    return 1;
}

/*---------------------- 函数实现 ----------------------*/
/**
  * @brief  初始化事件系统
  */
uint8_t Event_Init(void)
{
    stEventController.u32EventCount = 0;
    stEventController.u8EventPoolIndex = 0;
    stEventController.u8EventQueuePushIndex = 0;
    stEventController.u8EventQueuePopIndex = 0;
    stEventController.u8EventState = EVENT_STATE_IDLE;

    /* 初始化事件头链表 */
    for(uint8_t i = 0; i < EVENT_HEAD_LEN; i++) {
        stEventController.stEventHead[i].u8Id = i + 1;
        stEventController.stEventHead[i].pNext = NULL;
    }

    /* 初始化事件池 */
    for(uint8_t i = 0; i < EVENT_POOL_MAX_NUM; i++) {
        stEventController.stEventPool[i].u8Pri = 0;
        stEventController.stEventPool[i].pfnCallback = NULL;
        stEventController.stEventPool[i].pNext = NULL;
    }

    /* 初始化事件队列 */
    for(uint8_t i = 0; i < EVENT_HAPPENED_MAX_NUM; i++) {
        stEventController.EventQueue[i].u8Id = EVENT_NONE;
        stEventController.EventQueue[i].pDevice = NULL;
        stEventController.EventQueue[i].pArgs = NULL;
    }

    /* 注册系统周期性事件 */
    Event_Queue_Push(EVENT_SYS_CIRCLE, NULL, NULL);

    return 1;
}

/**
  * @brief  注册事件处理函数
  */
uint8_t Event_Register(void* pDevice,
                       uint8_t u8Id,
                       uint8_t u8Pri,
                       Event_Callback_TypeDef pfnCallback)
{
    /* 参数有效性检查 */
    if((stEventController.u8EventPoolIndex >= EVENT_POOL_MAX_NUM) ||
       (u8Id < 1) ||
       (u8Id > EVENT_ID_MAX)) {
        return 0;
    }

    /* 分配事件节点 */
    Event_Node_TypeDef* pstEvtNode =
            &stEventController.stEventPool[stEventController.u8EventPoolIndex++];
    pstEvtNode->u8Pri = u8Pri;
    pstEvtNode->pDevice = pDevice;
    pstEvtNode->pfnCallback = pfnCallback;
    pstEvtNode->pNext = NULL;

    /* 插入到对应事件链表 */
    Event_Head_Node_TypeDef* pstEvtHeadNode = &(stEventController.stEventHead[u8Id - 1]);

    /* 空链表 */
    Event_Node_TypeDef* pstOldNode = pstEvtHeadNode->pNext;
    if(pstOldNode == NULL)
    {
        pstEvtHeadNode->pNext = pstEvtNode;
        return 1;
    }
    /* 只有一个节点  */
    Event_Node_TypeDef* pstNewNode = pstOldNode->pNext;
    if(pstNewNode == NULL)
    {
        if(pstOldNode->u8Pri >= pstEvtNode->u8Pri)
        {
            pstOldNode->pNext = pstEvtNode;
            return 1;
        }
        else
        {
            pstEvtNode->pNext = pstOldNode;
            pstEvtHeadNode->pNext = pstEvtNode;
            return 1;
        }
    }
    /* 多节点遍历链表 */
    while(pstNewNode != NULL)
    {
        /* 最小优先级，插入末尾 */
        if(pstNewNode->u8Pri >= pstEvtNode->u8Pri)
        {
            pstNewNode->pNext = pstEvtNode;
            return 1;
        }
        /* 高优先级，插入头部 */
        else if(pstEvtNode->u8Pri > pstOldNode->u8Pri)
        {
            pstEvtNode->pNext = pstOldNode;
            pstEvtHeadNode->pNext = pstEvtNode;
            return 1;
        }
        /* 相同优先级，插入中间 */
        else if(pstEvtNode->u8Pri > pstNewNode->u8Pri &&
                pstEvtNode->u8Pri <= pstOldNode->u8Pri)
        {
            pstEvtNode->pNext = pstNewNode;
            pstOldNode->pNext = pstEvtNode;
            return 1;
        }
        pstOldNode = pstNewNode;
        pstNewNode = pstNewNode->pNext;
    }

    return 1;
}

/**
  * @brief  事件入队
  */
uint8_t Event_Queue_Push(uint8_t u8Id, void* pDevice, void* pArgs)
{
    /* 队列满或无效事件检查 */
    if((stEventController.u32EventCount == EVENT_HAPPENED_MAX_NUM) ||
       (u8Id == EVENT_NONE) ||
       (u8Id >= EVENT_ID_MAX) ||
       (stEventController.u8EventState != EVENT_STATE_IDLE)) {
        return 0;
    }

    stEventController.u8EventState = EVENT_STATE_BUSY;

    /* 循环队列处理 */
    if(stEventController.u8EventQueuePushIndex >= EVENT_HAPPENED_MAX_NUM) {
        stEventController.u8EventQueuePushIndex = 0;
    }

    /* 写入队列 */
    stEventController.EventQueue[stEventController.u8EventQueuePushIndex].u8Id = u8Id;
    stEventController.EventQueue[stEventController.u8EventQueuePushIndex].pDevice = pDevice;
    stEventController.EventQueue[stEventController.u8EventQueuePushIndex].pArgs = pArgs;
    stEventController.u8EventQueuePushIndex++;
    stEventController.u32EventCount++;

    stEventController.u8EventState = EVENT_STATE_IDLE;
    return 1;
}

/**
  * @brief  事件扫描
  */
void Event_Monitor(void)
{
    uint8_t u8EvtCount = stEventController.u32EventCount;
    while(u8EvtCount > 0)
    {
        Event_Queue_TypeDef stEvt = {
                .u8Id = EVENT_NONE,
                .pDevice = NULL,
                .pArgs = NULL
        };
        if(Event_Queue_Pop(&stEvt) != 1) break;
        Event_Emit(&stEvt);
        u8EvtCount--;
    }
}
